const UserPermission = require('../models/userPermission')
const RolePermission = require('../models/rolePermission')
const DepartmentPermission = require('../models/departmentPermission')
const logger = require('../utils/logger')
const cache = require('../utils/cache')
const User = require('../models/user')

class PermissionService {
  /**
   * 获取用户的最终权限
   * @param {number} userId - 用户ID
   * @param {number} departmentId - 部门ID
   * @returns {Promise<Object>} 权限配置
   */
  static async getUserPermissions(userId, departmentId) {
    try {
      // 1. 检查缓存
      const cacheKey = `user_permissions:${userId}`
      const cachedPermissions = await cache.get(cacheKey)
      if (cachedPermissions) {
        return JSON.parse(cachedPermissions)
      }

      // 2. 获取用户权限（最高优先级）
      const userPermission = await UserPermission.findOne({
        where: { user_id: userId }
      })
      if (userPermission) {
        await cache.set(cacheKey, JSON.stringify(userPermission.permissions))
        return userPermission.permissions
      }

      // 3. 获取部门权限（基础权限）
      const departmentPermission = await DepartmentPermission.findOne({
        where: { department_id: departmentId }
      })
      if (departmentPermission) {
        await cache.set(cacheKey, JSON.stringify(departmentPermission.permissions))
        return departmentPermission.permissions
      }

      // 4. 返回默认最小权限
      const defaultPermissions = {
        system: ['view'],
        business: ['view'],
        data: {
          scope: 'self',
          fields: ['basic']
        }
      }
      await cache.set(cacheKey, JSON.stringify(defaultPermissions))
      return defaultPermissions

    } catch (error) {
      logger.error('Get user permissions error:', error)
      throw error
    }
  }

  /**
   * 清除用户权限缓存
   * @param {number} userId - 用户ID
   */
  static async clearPermissionCache(userId) {
    try {
      const cacheKey = `user_permissions:${userId}`
      await cache.del(cacheKey)
    } catch (error) {
      logger.error('Clear permission cache error:', error)
      throw error
    }
  }

  /**
   * 检查用户是否有指定权限
   * @param {Object} userPermissions - 用户权限配置
   * @param {string} permissionType - 权限类型 (system|business)
   * @param {string} permission - 具体权限
   * @returns {boolean} 是否有权限
   */
  static hasPermission(userPermissions, permissionType, permission) {
    try {
      if (!userPermissions || !userPermissions[permissionType]) {
        return false
      }

      return userPermissions[permissionType].includes(permission) ||
             userPermissions[permissionType].includes('*')
    } catch (error) {
      logger.error('Check permission error:', error)
      return false
    }
  }

  /**
   * 检查用户是否有数据权限
   * @param {Object} userPermissions - 用户权限配置
   * @param {string} scope - 数据范围
   * @param {string} field - 字段
   * @returns {boolean} 是否有权限
   */
  static hasDataPermission(userPermissions, scope, field) {
    try {
      if (!userPermissions?.data) {
        return false
      }

      const { scope: userScope, fields } = userPermissions.data

      // 检查数据范围
      if (scope && userScope !== 'all' && userScope !== scope) {
        return false
      }

      // 检查字段权限
      if (field && !fields.includes(field) && !fields.includes('*')) {
        return false
      }

      return true
    } catch (error) {
      logger.error('Check data permission error:', error)
      return false
    }
  }

  /**
   * 清除角色相关的所有用户权限缓存
   * @param {number} roleId - 角色ID
   */
  static async clearRolePermissionCache(roleId) {
    try {
      // 获取该角色下的所有用户
      const users = await User.findAll({
        where: { role_id: roleId },
        attributes: ['id']
      })
      
      // 清除每个用户的权限缓存
      for (const user of users) {
        await this.clearPermissionCache(user.id)
      }
    } catch (error) {
      logger.error('Clear role permission cache error:', error)
      throw error
    }
  }

  /**
   * 清除部门相关的所有用户权限缓存
   * @param {number} departmentId - 部门ID
   */
  static async clearDepartmentPermissionCache(departmentId) {
    try {
      // 获取该部门下的所有用户
      const users = await User.findAll({
        where: { department_id: departmentId },
        attributes: ['id']
      })
      
      // 清除每个用户的权限缓存
      for (const user of users) {
        await this.clearPermissionCache(user.id)
      }
    } catch (error) {
      logger.error('Clear department permission cache error:', error)
      throw error
    }
  }

  /**
   * 清除使用指定模板的所有权限缓存
   * @param {number} templateId - 模板ID
   */
  static async clearTemplatePermissionCache(templateId) {
    try {
      // 获取使用该模板的所有用户
      const userPermissions = await UserPermission.findAll({
        where: { template_id: templateId },
        attributes: ['user_id']
      })
      
      // 获取使用该模板的所有角色
      const rolePermissions = await RolePermission.findAll({
        where: { template_id: templateId },
        include: [{
          model: User,
          attributes: ['id']
        }]
      })
      
      // 获取使用该模板的所有部门
      const departmentPermissions = await DepartmentPermission.findAll({
        where: { template_id: templateId },
        include: [{
          model: User,
          attributes: ['id']
        }]
      })
      
      // 收集所有需要清除缓存的用户ID
      const userIds = new Set()
      
      // 添加直接使用模板的用户
      userPermissions.forEach(up => userIds.add(up.user_id))
      
      // 添加通过角色使用模板的用户
      rolePermissions.forEach(rp => {
        rp.Users?.forEach(user => userIds.add(user.id))
      })
      
      // 添加通过部门使用模板的用户
      departmentPermissions.forEach(dp => {
        dp.Users?.forEach(user => userIds.add(user.id))
      })
      
      // 清除所有相关用户的权限缓存
      for (const userId of userIds) {
        await this.clearPermissionCache(userId)
      }
    } catch (error) {
      logger.error('Clear template permission cache error:', error)
      throw error
    }
  }
}

module.exports = PermissionService 